***********************************************************************************
***********************************************************************************
** Code for "Racial bias and U.S. Presidential Candidate Preference"
** L.J Zigerell
** For datasets, see: https://electionstudies.org/
***********************************************************************************
***********************************************************************************

***********************************************************************************
** "Equal" section, for 2008, 2012, 2016, and 2020
***********************************************************************************
** Below is the "equal" analyses for all included years: 2008, 2012, 2016, and 2020.
** Run the commands in this "equal" section after the commands even farther below for each year.
** The purpose of this "equal" section is to get four variables per year:
** [1] FTeq, coded 1 for rating Blacks, Hispanics, Asians, and Whites equal to each other, and 0 otherwise (including non-responses)
** [2] FTclose
** [3] voteGOPprez, as a two-party vote outcome
** [4] party3 (1=Democrat, 2=Independent, 3=Republican), based on pre-election surveys
** To properly get [1], get FTblack, FThispn, FTasian, and FTwhite on 0-to-100 scales, with -9 for non-responses and . for respondents who didn't get a thermometer
***********************************************************************************
***********************************************************************************

sum  FTblack FThispn FTasian FTwhite
tab1 FTblack FThispn FTasian FTwhite

// Get FTequal thermo cases that included refusals in the omitted category

gen     FTeq = 0
replace FTeq = 1 if (FTblack==FThispn) & (FTblack==FTasian) & (FTblack==FTwhite) & (FThispn==FTasian) & (FThispn==FTwhite) & (FTasian==FTwhite) & FTblack!=. & FThispn!=. & FTasian!=. & FTwhite!=.
replace FTeq = . if FTblack==.  | FThispn==.  | FTasian==.  | FTwhite==.
replace FTeq = 0 if FTblack==-9 | FThispn==-9 | FTasian==-9 | FTwhite==-9
tab     FTeq, mi
tab     FTeq

sum FTblack FThispn FTasian FTwhite if FTeq==1

// Get FTclose thermo cases that included refusals in the omitted category (FTclose is 5 points or fewer apart)

gen     FTclose = 0
replace FTclose = 1 if (abs(FTblack-FThispn)<=5) & (abs(FTblack-FTasian)<=5) & (abs(FTblack-FTwhite)<=5) & (abs(FThispn-FTasian)<=5) & (abs(FThispn-FTwhite)<=5) & (abs(FTasian-FTwhite)<=5)
replace FTclose = . if FTblack==.  | FThispn==.  | FTasian==.  | FTwhite==.
replace FTclose = 0 if FTblack==-9 | FThispn==-9 | FTasian==-9 | FTwhite==-9
tab     FTclose, mi
tab     FTclose

tab FTeq FTclose, mi
tab FTeq FTclose

sum FTblack FThispn FTasian FTwhite if FTclose==1

// [Figure 2] Run an overall assessment of the effect of racial bias

svy: prop voteGOPprez2              , level(83.4)
svy: prop voteGOPprez2 if FTeq==1   , level(83.4)
svy: prop voteGOPprez2 if FTclose==1, level(83.4)

// [Figure 3] Proportion of equal ratings by vote choice

svy: prop FTeq if voteGOPprez2==1, level(83.4)
svy: prop FTeq if voteGOPprez2==0, level(83.4)

// [Figure S2] Proportion of equal ratings

svy: prop FTeq if race==1                        , level(83.4) // NH White
svy: prop FTeq if race==2                        , level(83.4) // Not NH White
svy: prop FTeq if party3=="3. Republican" :party3, level(83.4)
svy: prop FTeq if party3=="2. Independent":party3, level(83.4)
svy: prop FTeq if party3=="1. Democrat"   :party3, level(83.4)
svy: prop FTeq if party3==3                      , level(83.4) // Republican
svy: prop FTeq if party3==2                      , level(83.4) // Independent
svy: prop FTeq if party3==1                      , level(83.4) // Democrat

***********************************************************************************
***********************************************************************************
** Code for the ANES 2008 Time Series Study (dataset date of 2015-05-19)
***********************************************************************************
***********************************************************************************

// Code racial thermometers

desc V085064y V085064a V085064v V085065c

clonevar FTblack = V085064y
clonevar FThispn = V085064a 
clonevar FTasian = V085064v
clonevar FTwhite = V085065c

tab1   FTblack FThispn FTasian FTwhite
recode FTblack FThispn FTasian FTwhite (-9/-6=-9) (-2=.)
tab1   FTblack FThispn FTasian FTwhite

// Code vote choice

tab    V085044a
tab    V085044a, nol
recode V085044a (1=0) (3=1) (-9/-1 3/9=.), gen(voteGOPprez2)
tab    V085044a voteGOPprez2, mi

// Code race

codebook V081102
recode   V081102 (1=1 "NH White") (2/6=2 "Not NH White"), gen(race)
tab      V081102 race
tab      V081102 race, mi

// Code party3 [pre-election]

codebook V083097 
recode   V083097 (1=1 "1. Democrat") (3=2 "2. Independent") (2=3 "3. Republican") (-9/-1 4/9=99 "99. Other"), gen(party3)
tab      V083097 party3, mi

// Survey weights [f2f / acasi]

svyset [pweight=V080102]

***********************************************************************************
***********************************************************************************
** Code for the ANES 2012 Time Series Study (dataset date of 2016-05-24)
***********************************************************************************
***********************************************************************************

// Code racial thermometers

desc ftcasi_black ftcasi_hisp ftcasi_asian ftcasi_white

clonevar FTblack = ftcasi_black
clonevar FThispn = ftcasi_hisp
clonevar FTasian = ftcasi_asian
clonevar FTwhite = ftcasi_white

tab1   FTblack FThispn FTasian FTwhite
recode FTblack FThispn FTasian FTwhite (-9/-8=-9) (-7/-1=.)
tab1   FTblack FThispn FTasian FTwhite

// Code vote choice

tab    presvote2012_x
tab    presvote2012_x, nol
recode presvote2012_x (1=0) (2=1) (-9/-1 3/9=.), gen(voteGOPprez2)
tab    presvote2012_x voteGOPprez2, mi

// Code race

codebook dem_raceeth_x
recode   dem_raceeth_x (1=1 "NH White") (2/6=2 "Not NH White"), gen(race)
tab      dem_raceeth_x race
tab      dem_raceeth_x race, mi

// Code party3 [pre-election]

codebook pid_self
recode   pid_self (1=1 "1. Democrat") (3=2 "2. Independent") (2=3 "3. Republican") (-9/0 4/9=99 "99. Other"), gen(party3)
tab      pid_self party3, mi

// Survey weights

svyset [pweight=weight_full], strata(strata_full) psu(psu_full) singleunit(centered)
svyset [pweight=weight_ftf] , strata(strata_ftf)  psu(psu_ftf)  singleunit(centered)
svyset [pweight=weight_web] ,                                   singleunit(centered)

***********************************************************************************
***********************************************************************************
** Code for the ANES 2016 Time Series Study (dataset date of 2019-09-04)
***********************************************************************************
***********************************************************************************

// Code racial thermometers

desc V162312 V162311 V162310 V162314

clonevar FTblack = V162312
clonevar FThispn = V162311
clonevar FTasian = V162310
clonevar FTwhite = V162314

tab1   FTblack FThispn FTasian FTwhite
recode FTblack FThispn FTasian FTwhite (-9=-9) (-7/-1=.)
tab1   FTblack FThispn FTasian FTwhite

// Code vote choice

tab    V162062x
tab    V162062x, nol
recode V162062x (1=0) (2=1) (-9/-1 3/9=.), gen(voteGOPprez2)
tab    V162062x voteGOPprez2, mi

// Code race

codebook V161310x 
recode   V161310x (1=1 "NH White") (2/6=2 "Not NH White"), gen(race)
tab      V161310x race
tab      V161310x race, mi

// Code party3 [pre-election]

codebook V161155
recode   V161155 (1=1 "1. Democrat") (3=2 "2. Independent") (2=3 "3. Republican") (-9/0 4/9=99 "99. Other"), gen(party3)
tab      V161155 party3, mi

// Survey weights

svyset [pweight=V160102] , strata(V160201)  psu(V160202)  singleunit(centered)
svyset [pweight=V160102f], strata(V160201f) psu(V160202f) singleunit(centered)
svyset [pweight=V160102w], strata(V160201w) psu(V160202w) singleunit(centered)

***********************************************************************************
***********************************************************************************
** Code for the ANES 2020 Social Media Study (dataset date of 2021-03-08)
***********************************************************************************
***********************************************************************************

// Code racial thermometers

desc ftblack fthisp ftasians ftwhite

clonevar FTblack = ftblack
clonevar FThispn = fthisp
clonevar FTasian = ftasians
clonevar FTwhite = ftwhite

tab1   FTblack FThispn FTasian FTwhite
tab1   FTblack FThispn FTasian FTwhite, nol
recode FTblack FThispn FTasian FTwhite (-7/-1=.)
tab1   FTblack FThispn FTasian FTwhite

// Code vote choice

codebook w2presvtwho
recode   w2presvtwho (2=0) (-9/-1 3=.), gen(voteGOPprez2)
tab      w2presvtwho voteGOPprez2, mi

// Code race

codebook profile_racethnicity   
recode   profile_racethnicity (1=1 "NH White") (2/6=2 "Not NH White"), gen(race)
tab      profile_racethnicity race
tab      profile_racethnicity race, mi

// Code party3 [pre-election]

codebook pid1d pid1r

gen     party3 = 99
replace party3=1 if pid1d==1 | pid1r==1
replace party3=2 if pid1d==3 | pid1r==3
replace party3=3 if pid1d==2 | pid1r==2
tab     party3

tab pid7x party3 

label define party3 1 "1. Democrat" 2 "2. Independent" 3 "3. Republican"
label values party3 party3
tab party3

// Survey weights

svyset [pweight=weight_post]


***********************************************************************************
***********************************************************************************
** Code for the ANES 2020 Time Series Study (dataset date of 2021-07-19)
***********************************************************************************
***********************************************************************************

// Check number of post-election interviews [N=7453]

tab V200004 

// Check number of post-election interviews that received the FTs [N=7361]

desc V202477 V202478 V202480 V202479 V202482
tab1 V202477 V202478 V202480 V202479 V202482
sum V200001                                  if (((V202477>=0 & V202477<=100) | V202477==-9) | ((V202478>=0 & V202478<=100) | V202478==-9)) & ((V202480>=0 & V202480<=100) | V202480==-9) & ((V202479>=0 & V202479<=100) | V202479==-9) & ((V202482>=0 & V202482<=100) | V202482==-9)
tab1 V202477 V202478 V202480 V202479 V202482 if (((V202477>=0 & V202477<=100) | V202477==-9) | ((V202478>=0 & V202478<=100) | V202478==-9)) & ((V202480>=0 & V202480<=100) | V202480==-9) & ((V202479>=0 & V202479<=100) | V202479==-9) & ((V202482>=0 & V202482<=100) | V202482==-9)

***********************************************************************************
** Racial groups
***********************************************************************************

tab      V201549x 
recode   V201549x (1=1 "NH White") (2/6=2 "Not NH White"), gen(race)
tab      V201549x race
tab      V201549x race, mi

tab    V201549x, mi
recode V201549x (-9/-1 2/6=0)          , gen(Rwhite)
recode V201549x (2/6=1) (-9 -8 1=0)    , gen(Rnonwh)
recode V201549x (-9/-1 1 3/6=0) (2=1)  , gen(Rblack)
recode V201549x (-9/-1 1/2 4/6=0) (3=1), gen(Rhispn)
recode V201549x (-9/-1 1/3 5/6=0) (4=1), gen(Rasian)

tab V201549x Rwhite, mi
tab V201549x Rnonwh, mi
tab V201549x Rblack, mi
tab V201549x Rhispn, mi
tab V201549x Rasian, mi

***********************************************************************************
** Racial feeling thermometers
***********************************************************************************

// N=6662 rated all four racial groups
sum V200001 if ((V202477>=0 & V202477<=100) | (V202478>=0 & V202478<=100)) & (V202480>=0 & V202480<=100) & (V202479>=0 & V202479<=100) & (V202482>=0 & V202482<=100)

// N=699 did not rate at least one racial group 
sum V200001 if V202477==-9 | V202478==-9 | V202480==-9 | V202479==-9 | V202482==-9

// N=7361 rated all four racial groups or skipped at least one racial group rating
sum V200001 if (((V202477>=0 & V202477<=100) | (V202478>=0 & V202478<=100)) & (V202480>=0 & V202480<=100) & (V202479>=0 & V202479<=100) & (V202482>=0 & V202482<=100)) | (V202477==-9 | V202478==-9 | V202480==-9 | V202479==-9 | V202482==-9)

// N=7361 rated or skipped all four racial groups
sum V200001 if (((V202477>=0 & V202477<=100) | V202477==-9) | ((V202478>=0 & V202478<=100) | V202478==-9)) & ((V202480>=0 & V202480<=100) | V202480==-9) & ((V202479>=0 & V202479<=100) | V202479==-9) & ((V202482>=0 & V202482<=100) | V202482==-9)

// Code racial thermometers

codebook V202477 V202478 V202480 V202479 V202482
tab1     V202477 V202478 V202480 V202479 V202482, mi
desc     V202477 V202478 V202480 V202479 V202482

gen     FTasian = .
replace FTasian = V202477 if V202478==-1
replace FTasian = V202478 if V202477==-1
tab     FTasian
sum     FTasian
label   variable FTasian "POST: Feeling thermometer: Asians/Asian-Americans"

clonevar FTblack = V202480
clonevar FThispn = V202479
clonevar FTwhite = V202482

desc     FTblack FThispn FTasian FTwhite

// Check FTasian coding

clonevar FTaa = V202477
clonevar FTab = V202478
recode   FTaa FTab (-100/-1=.)
egen     FTasianX = rowmean(FTaa FTab)
tab      FTasianX
sum      FTasianX FTasian if FTasianX>=0 & FTasian>=0

// Get racial thermos from 0 to 100 with a -9 for refusals

tab1   FTblack FThispn FTasian FTwhite 
recode FTblack FThispn FTasian FTwhite (-7 -6 -5 -4=.)
tab1   FTblack FThispn FTasian FTwhite 
sum    FTblack FThispn FTasian FTwhite 

// Rated Whites colder/warmer than all other racial groups

label   define FTwhite4 1 "[1] Rated Whites lower/colder than Blacks, Hispanics, and Asians" 2 "[2] Equal ratings for Whites, Blacks, Hispanics, and Asians" 3 "[3] Rated Whites higher/warmer than Blacks, Hispanics, and Asians" 98 "[98] Residual" 99 "[99] Did not rate at least one group" 
gen     FTwhite4 = 98
replace FTwhite4 = 1  if (FTwhite < FTblack) & (FTwhite < FThispn) & (FTwhite < FTasian)                                                                & FTblack!=. & FThispn!=. & FTasian!=. & FTwhite!=.
replace FTwhite4 = 2  if (FTasian==FThispn)  & (FTasian==FTblack)  & (FTasian==FTwhite)  & (FThispn==FTblack) & (FThispn==FTwhite) & (FTblack==FTwhite) & FTblack!=. & FThispn!=. & FTasian!=. & FTwhite!=.
replace FTwhite4 = 3  if (FTwhite > FTblack) & (FTwhite > FThispn) & (FTwhite > FTasian)                                                                & FTblack!=. & FThispn!=. & FTasian!=. & FTwhite!=.
replace FTwhite4 = 99 if FTblack==-9 | FThispn==-9 | FTasian==-9 | FTwhite==-9
replace FTwhite4 = .  if FTblack==. | FThispn==. | FTasian==. | FTwhite==.
label   values FTwhite4 FTwhite4
tab     FTwhite4

***********************************************************************************
** Other measures of racial attitudes
***********************************************************************************

// Hardworking

tab1     V202515 V202516 
tab      V202515 V202516 if (V202515==-9 | (V202515>=1 & V202515<=7)) & (V202516==-9 | (V202516>=1 & V202516<=7))
clonevar HWw = V202515
clonevar HWb = V202516
recode   HWw HWb (-7/-1=.)
tab      HWw HWb
label    define HWwb 1 "[1] Whites more lazy" 2 "[2] Equal rating" 3 "[3] Blacks more lazy" 99 "[98] Residual"
gen      HWwb = 98
replace  HWwb = 1 if ((HWb - HWw)<0) & HWb!=-9 & HWw!=-9 & HWb!=. & HWw!=.
replace  HWwb = 2 if (HWb == HWw)    & HWb!=-9 & HWw!=-9 & HWb!=. & HWw!=.
replace  HWwb = 3 if ((HWb - HWw)>0) & HWb!=-9 & HWw!=-9 & HWb!=. & HWw!=.
replace  HWwb = . if                                       HWb==. | HWw==.
tab      HWwb
label    values HWwb HWwb
tab      HWwb
tab      V202515 V202516 if HWwb==1 , mi
tab      V202515 V202516 if HWwb==2 , mi
tab      V202515 V202516 if HWwb==3 , mi
tab      V202515 V202516 if HWwb==98, mi

// Violent

tab1     V202521 V202522
tab      V202521 V202522 if (V202521==-9 | (V202521>=1 & V202521<=7)) & (V202522==-9 | (V202522>=1 & V202522<=7))
clonevar VIw = V202521 
clonevar VIb = V202522
recode   VIw VIb (-7/-1=.)
tab      VIw VIb
label    define VIwb 1 "[1] Whites more violent" 2 "[2] Equal rating" 3 "[3] Blacks more violent"
gen      VIwb = 98
replace  VIwb = 1 if ((VIb - VIw)<0) & VIb!=-9 & VIw!=-9 & VIb!=. & VIw!=.
replace  VIwb = 2 if (VIb == VIw)    & VIb!=-9 & VIw!=-9 & VIb!=. & VIw!=.
replace  VIwb = 3 if ((VIb - VIw)>0) & VIb!=-9 & VIw!=-9 & VIb!=. & VIw!=.
replace  VIwb = . if                                       VIb==. | VIw==.
tab      VIwb
label    values VIwb VIwb
tab      VIwb
tab      V202521 V202522 if VIwb==1 , mi
tab      V202521 V202522 if VIwb==2 , mi
tab      V202521 V202522 if VIwb==3 , mi
tab      V202521 V202522 if VIwb==98, mi

// Only Whites have too much influence

tab1    V202494 V202495 V202496 V202497
desc    V202494 V202495 V202496 V202497
di      8280 - 77 - 754 - 89 // Expected sample size of 7360
label   define infW 0 "[0] Residual" 1 "[1] Only Whites have too much influence" 2 "[2] Equal influence for all four"
gen     infW = 0
replace infW = 1 if V202494==1 & (V202495==2 | V202495==3) & (V202496==2 | V202496==3) & (V202497==2 | V202497==3)
tab     infW
replace infW = 2 if (V202494==V202495) & (V202495==V202496) & (V202496==V202497) & (V202494!=-9 & V202495!=-9 & V202496!=-9 & V202497!=-9)
replace infW = . if (V202494>-9 & V202494<1) | (V202495>-9 & V202495<1) | (V202496>-9 & V202496<1) | (V202497>-9 & V202497<1) 
label   values infW infW
tab     infW
tab V202494 infW, mi
tab V202495 infW, mi
tab V202496 infW, mi
tab V202497 infW, mi
* order infW V202494 V202495 V202496 V202497 // For checking in Stata
* sort infW                                  // For checking in Stata

// Racial resentment

tab1     V202300 V202301 V202302 V202303
desc     V202300 V202301 V202302 V202303
clonevar RR1 = V202300
clonevar RR2 = V202301
clonevar RR3 = V202302
clonevar RR4 = V202303
recode   RR1 RR2 RR3 RR4 (-9/-1=.)
sum      RR1 RR2 RR3 RR4
pwcorr   RR1 RR2 RR3 RR4
desc     RR1 RR2 RR3 RR4

gen     RRsum = RR2 + RR3 - RR1 - RR4 
factor  RR1 RR2 RR3 RR4, pcf
predict RRfactor
pwcorr  RRfactor RRsum, sig obs
sum     RRfactor RRsum
gen RRsum01 = (RRsum+8)/16
sum RRsum01
gen RRsum16 = RRsum + 8
sum RRsum16
gen RR01 = RRsum16/16
sum RR01

tab V202300 RRsum16 // Check order
tab V202301 RRsum16 // Check order
tab V202302 RRsum16 // Check order
tab V202303 RRsum16 // Check order

***********************************************************************************
** Partisanship [pre-election]
***********************************************************************************

tab      V201228
recode   V201228 (1=1 "1. Democrat") (3=2 "2. Independent") (2=3 "3. Republican") (-9/0 4/9=99 "99. Other"), gen(party3)
tab      V201228 party3, mi

***********************************************************************************
** 2020 U.S. presidential vote choice
***********************************************************************************

// Trump / Biden vote

tab    V202110x
recode V202110x (1=0) (2=1) (-9/-1 3/5=.), gen(voteGOPprez2)
tab    V202110x voteGOPprez2, mi

***********************************************************************************
** ANES 2020 analysis
***********************************************************************************

// Survey weights [full sample]

desc V200010b V200010d V200010c
svyset [pweight=V200010b], strata(V200010d) psu(V200010c) singleunit(centered)
sum V200010b if V200010b!=. & V200010b!=0

// Survey weights [web sample]

desc V200012b V200012d V200012c
svyset [pweight=V200012b], strata(V200012d) psu(V200012c) singleunit(centered)
sum V200012b if V200012b!=. & V200012b!=0

// [Figure 1] % in each anti-White / pro-White group

tab FTwhite4

svy                : prop FTwhite4, level(83.4)
svy, subpop(Rwhite): prop FTwhite4, level(83.4)
svy, subpop(Rnonwh): prop FTwhite4, level(83.4)
svy, subpop(Rblack): prop FTwhite4, level(83.4)
svy, subpop(Rhispn): prop FTwhite4, level(83.4)
svy, subpop(Rasian): prop FTwhite4, level(83.4)

svy                : prop FTwhite4 if voteGOPprez2==1 | voteGOPprez2==0, level(83.4)
svy, subpop(Rwhite): prop FTwhite4 if voteGOPprez2==1 | voteGOPprez2==0, level(83.4)
svy, subpop(Rnonwh): prop FTwhite4 if voteGOPprez2==1 | voteGOPprez2==0, level(83.4)

codebook party3

svy: prop FTwhite4 if party3=="3. Republican":party3 , level(83.4)
svy: prop FTwhite4 if party3=="2. Independent":party3, level(83.4)
svy: prop FTwhite4 if party3=="1. Democrat": party3  , level(83.4)

svy, subpop(Rwhite): prop FTwhite4 if party3=="3. Republican":party3 , level(83.4)
svy, subpop(Rwhite): prop FTwhite4 if party3=="2. Independent":party3, level(83.4)
svy, subpop(Rwhite): prop FTwhite4 if party3=="1. Democrat": party3  , level(83.4)

svy: prop FTwhite4 if party3==3, level(83.4) // Republican
svy: prop FTwhite4 if party3==2, level(83.4) // Independent
svy: prop FTwhite4 if party3==1, level(83.4) // Democrat

svy, subpop(Rwhite): prop FTwhite4 if party3==3, level(83.4) // Republican
svy, subpop(Rwhite): prop FTwhite4 if party3==2, level(83.4) // Independent
svy, subpop(Rwhite): prop FTwhite4 if party3==1, level(83.4) // Democrat

// [main text] Check against other anti-White / pro-White measures

svy, subpop(Rwhite): prop VIwb, over(FTwhite4) level(83.4)
svy, subpop(Rwhite): prop HWwb, over(FTwhite4) level(83.4)
svy, subpop(Rwhite): prop infW, over(FTwhite4) level(83.4)
svy, subpop(Rwhite): mean RR01, over(FTwhite4) level(83.4)
svy, subpop(Rnonwh): mean RR01, over(FTwhite4) level(83.4)
svy, subpop(Rblack): mean RR01, over(FTwhite4) level(83.4)